﻿#include "ssLogger.h"
#ifdef SS_USE_WINDOWS
#include <windows.h>
#include <direct.h>
#else
#include <sys/stat.h>
#endif
#include "../time/ssTime.h"
#include "../ssAssert.h"


namespace StarSeeker
{

ssLogger::ssLogger(u8 type, const char* path)
{
	memset(m_lastDate, 0, sizeof(m_lastDate));
	m_pFile = 0;
	m_info.GetInfo();
	if (path)
	{
		m_folder = path;
	}
	else
	{
		m_folder = "./";
		m_folder += m_info.m_name;
		m_folder += "_logs";
	}
	m_subsection = type == 1 ? 1 : 0;
}

ssLogger::~ssLogger()
{
	CloseFile();
}

void ssLogger::PrintDebug(const char *pLogString)
{
#ifndef SS_NONE_PRINT
	FormatString(0, pLogString);
#endif
}

void ssLogger::PrintDebugEx(const char *pLogString, ...)
{
#ifndef SS_NONE_PRINT
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(0, pLogString, arglist);
	va_end(arglist);
#endif
}

void ssLogger::Print(const char *pLogString)
{
	FormatString(1, pLogString);
}

void ssLogger::PrintEx(const char *pLogString, ...)
{
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(1, pLogString, arglist);
	va_end(arglist);
}

void ssLogger::Error(const char *pLogString)
{
	FormatString(3, pLogString);
}

void ssLogger::ErrorEx(const char *pLogString, ...)
{
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(3, pLogString, arglist);
	va_end(arglist);
}

void ssLogger::PrintFile(const char *pLogString)
{
	FormatString(2, pLogString);
}

void ssLogger::PrintFileEx(const char *pLogString, ...)
{
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(2, pLogString, arglist);
	va_end(arglist);
}

void ssLogger::HandleMessage(ssMsg_s &m)
{
	if (m.msgID == 111)
	{
		char* str = (char*)m.param[0];
		if (m.subID == 0)
		{
#ifdef SS_USE_WINDOWS
			::OutputDebugStringA(str);
#endif
			printf(str);
		}
		else if (m.subID == 1 || m.subID == 3)
		{
			printf(str);
			SaveToFile(str);
		}
		else if (m.subID == 2)
		{
			SaveToFile(str);
		}
		delete [] str;
	}
}
// 保存到文件
void ssLogger::SaveToFile(const char * pStr)
{
	//是否新建文件
	MakeDir();

	CloseFile();
	m_pFile = ::fopen(m_filePath.GetString(), "a");
	if (m_pFile)
	{
		::fprintf(m_pFile, pStr);
		::fclose(m_pFile);
		m_pFile = 0;
	}
}
// 打开文件流
void ssLogger::MakeDir()
{
	bool change = false;
	char szTime[32] = { 0 };
	if (m_subsection==1)
	{
		ssTime::GetLocalTimeYMDH(szTime);
		if (strcmp(szTime, m_lastDate))
		{
			ssTime::GetLocalTimeYMDH(m_lastDate);
			change = true;
		}
	} 
	else
	{
		ssTime::GetLocalTimeYMD(szTime);
		if (strcmp(szTime, m_lastDate))
		{
			ssTime::GetLocalTimeYMD(m_lastDate);
			change = true;
		}
	}
	if (change)
	{
		//建立logs文件夹
#ifdef SS_USE_WINDOWS
		::_mkdir(m_folder.GetString());
#else
		::mkdir(m_folder.GetString(), S_IRWXU);
#endif
		//建立日期文件
		m_filePath = m_folder;
		m_filePath += "/";
		m_filePath += m_lastDate;
		m_filePath += ".log";
	}
}
// 关闭文件
void ssLogger::CloseFile()
{
	if (m_pFile)
	{
		::fclose(m_pFile);
		m_pFile = 0;
	}
}

void ssLogger::FormatString(char lv, const char* str)
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);

	u32 len = StrLen(str);
	char* logStr = new char[len+20];
	if (lv == 3)
		snprintf(logStr, len+19, "[%s][ERROR]%s\n", tempTime, str);
	else
		snprintf(logStr, len+19, "[%s]%s\n", tempTime, str);

	ssMsg_s msg( 111, lv, (ulint)logStr );
	PostMsg(msg);
}

// 格式化字符串
void ssLogger::FormatStringEx( char lv, const char* str, va_list &vaList )
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	char tempBuf[LOG_PRINT_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);
	// 处理变长参数
	int len = vsnprintf(tempBuf, LOG_PRINT_LEN - 1, str, vaList);
	if (len <= 0)
	{
		memcpy(tempBuf, "vsnprintf error!\n", 17);
	}
	char* logStr = new char[LOG_STR_LEN];
	if (lv == 3)
		snprintf(logStr, LOG_STR_LEN - 1, "[%s][ERROR]%s\n", tempTime, tempBuf);
	else
		snprintf(logStr, LOG_STR_LEN - 1, "[%s]%s\n", tempTime, tempBuf);

	ssMsg_s msg(111, lv, (ulint)logStr);
	PostMsg(msg);
}

}
